package com.limit.rateLimit;

import com.limit.service.TimeWindowLimit;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

/**
 * @作者: 林江
 * @创建时间: 2023/12/21
 * @功能: 滑动时间窗口
 */
public class SlideTimeWindow implements TimeWindowLimit {
    /*---------------限制每秒钟10个请求--------------------------*/
    private int req; // 时间窗口的总请求数
    private int limit = 10; // 限制请求数阈值
    private int interval = 200; // 时间窗口间隔时间
    private int size = 5; // 窗格数

    private LinkedList<Integer> slots = new LinkedList<>(); // 窗格存储

    public SlideTimeWindow() {
        slots.addLast(0);
        new Thread(() -> {
            while (true) {
                try {
                    TimeUnit.MILLISECONDS.sleep(interval);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                slots.addLast(0);

                if (slots.size() > size) {
                    req = req - slots.peekFirst(); // 每个窗格被移除时，请求数将减少

                    slots.removeFirst();
                }
            }
        }).start();
    }

    @Override
    public synchronized boolean limit() {
        if ((req + 1) > limit) {
            return true;
        }

        slots.set(slots.size() - 1, slots.peekLast() + 1); // 最新的窗格里面的请求数+1
        req++;
        return false;
    }
}
